using System;
using System.Collections.Generic;
using System.Web.Security;
using System.Web.Script.Serialization;
using System.Linq;
using System.Web.Mvc;
using System.Web.UI;
using System.IO;

using MvcCms.Data.Pagination;
using MvcCmsOptIn.Service;
using MvcCms.Service.Logging;
using MvcCms.Data;
using MvcCms.Service.Code;
using MvcCms.Service.Models;
using MvcCms.Service;

namespace MvcCmsOptIn.Controllers
{
    public class MvcCmsOptInAjaxController : MvcCms.Service.Code.BaseClasses.MvcCmsControllerBase
    {
        #region Constructors
        private readonly IOptInService _service;
        private readonly IAccountService _accountService;
        public MvcCmsOptInAjaxController(IOptInService optinService, IAccountService accountService)
        {
            _accountService = accountService;
            _service = optinService;
        }
        #endregion

        public JsonResult AddFriend(OptInSubscriber subscriberToAdd)
        {
            try
            {
                var subscriberExists = _service.GetSubscriber(subscriberToAdd.EMail);
                if (subscriberExists != null)
                {
                    return Json(new { result = "success" });
                }
                _service.CreateSubscriber(subscriberToAdd);
                return Json(new { result = "success" });               
            }
            catch (Exception ex)
            {
                AppLogging.GetLogger().Error(ex.Message, ex);
                return Json(new { error = ex.Message });
            }
        }        
        
        [Authorize(Roles = "Admin, Editor")]
        public JsonResult SendNewsLetter(int newsLetterId, int subscriberId)
        {
            try
            {
                if (_service.SendNewsLetter(newsLetterId, subscriberId))
                {
                    return Json(new { result = "success" });
                }
                return Json(new { error = "There was a problem sending a newsletter.  Do you want to continue?" });
            }
            catch (Exception ex)
            {
                AppLogging.GetLogger().Error(ex.Message, ex);
                return Json(new { error = ex.Message });
            }
        }

        [Authorize(Roles = "Admin, Editor")]
        public JsonResult AddListToNewsLetter(int newsLetterId, int listId)
        {
            try
            {
                if (_service.AddListToNewsLetter(newsLetterId, listId))
                {
                    return Json(new { result = "success" });
                }
                return Json(new { error = "There was a problem adding the list to the newsletter." });
            }
            catch (Exception ex)
            {
                AppLogging.GetLogger().Error(ex.Message, ex);
                return Json(new { error = ex.Message });
            }
        }

        [Authorize(Roles = "Admin, Editor")]
        public JsonResult RemoveListFromNewsLetter(int newsLetterId, int listId)
        {
            try
            {
                if (_service.RemoveListFromNewsLetter(newsLetterId, listId))
                {
                    return Json(new { result = "success" });
                }
                return Json(new { error = "There was a problem removing the list from the newsletter." });
            }
            catch (Exception ex)
            {
                AppLogging.GetLogger().Error(ex.Message, ex);
                return Json(new { error = ex.Message });
            }
        }

        [Authorize(Roles = "Admin, Editor")]
        public JsonResult AddListToSubscriber(int subscriberId, int listId, bool confirmed, bool useHTML, string ipAddress)
        {
            try
            {
                if (_service.AddListToSubscriber(subscriberId, listId, confirmed, useHTML, ipAddress))
                {
                    return Json(new { result = "success" });
                }
                return Json(new { error = "There was a problem adding the list to the subscriber." });
            }
            catch (Exception ex)
            {
                AppLogging.GetLogger().Error(ex.Message, ex);
                return Json(new { error = ex.Message });
            }
        }

        [Authorize(Roles = "Admin, Editor")]
        public JsonResult RemoveListFromSubscriber(int subscriberId, int listId)
        {
            try
            {
                if (_service.RemoveListFromSubscriber(subscriberId, listId))
                {
                    return Json(new { result = "success" });
                }
                return Json(new { error = "There was a problem removing the list from the subscriber." });
            }
            catch (Exception ex)
            {
                AppLogging.GetLogger().Error(ex.Message, ex);
                return Json(new { error = ex.Message });
            }
        }

        [ValidateInput(false)]
        [Authorize(Roles = "Admin, Editor")]
        public JsonResult SaveNewsLetter(OptInNewsLetter editedNewsLetter)
        {
            try
            {
                var user = _accountService.GetUser();
                editedNewsLetter.AdminID = user.UserID;

                OptInNewsLetter newsLetterToEdit = null;

                if (editedNewsLetter.NewsLetterID == 0)
                {
                    if (_service.CreateNewsLetter(editedNewsLetter))
                    {
                        return Json(new { result = "success", newsLetterID = editedNewsLetter.NewsLetterID });
                    }
                    return Json(new { error = "There was a problem creating the newsletter." });
                }
                else
                {
                    newsLetterToEdit = _service.GetNewsLetter(editedNewsLetter.NewsLetterID);
                    newsLetterToEdit.Name = editedNewsLetter.Name;
                    newsLetterToEdit.FromName = editedNewsLetter.FromName;
                    newsLetterToEdit.FromEmail = editedNewsLetter.FromEmail;
                    newsLetterToEdit.AdminID = editedNewsLetter.AdminID;
                    newsLetterToEdit.LastModified = DateTime.Now;
                    newsLetterToEdit.Subject = editedNewsLetter.Subject;
                    newsLetterToEdit.Text = editedNewsLetter.Text;
                    newsLetterToEdit.Url = editedNewsLetter.Url;
                    newsLetterToEdit.UrlText = editedNewsLetter.UrlText;                    
                    newsLetterToEdit.HTML = editedNewsLetter.HTML;

                    if (_service.EditNewsLetter(newsLetterToEdit))
                    {
                        return Json(new { result = "success", newsLetterID = editedNewsLetter.NewsLetterID });
                    }
                    return Json(new { error = "There was a problem saving the newsletter." });
                }
            }
            catch (Exception ex)
            {
                AppLogging.GetLogger().Error(ex.Message, ex);
                return Json(new { error = ex.Message });
            }
        }

        [Authorize(Roles = "Admin, Editor")]
        public JsonResult ListNewsLetters(DataTablesRequest dataTablesRequest)
        {
            try
            {
                var columnsToReturn = "Name,Recipients,Status,ReleaseDate,Send,Edit,Delete";
                var dtoNewsLetters = _service.ListNewsLetters(dataTablesRequest, columnsToReturn);
                var dataTablesFormatted = dtoNewsLetters
                    .Select(n => new string[] {    
                                n.Name, 
                                n.Recipients.ToString(), 
                                n.Status,
                                n.ReleaseDate.HasValue ? ((DateTime?) null).ToString() : n.ReleaseDate.ToString(),
                                "<a href=\"/optin-manager/sendnewsletter/"+n.NewsLetterID+"\"><img border=\"0\" alt=\"edit\" src=\"/areas/mvccmsoptin/content/buttons/sendemail.gif\" //></a>",
                                "<a href=\"/optin-manager/editnewsletter/"+n.NewsLetterID+"\"><img border=\"0\" alt=\"edit\" src=\"/areas/mvccmsoptin/content/buttons/edit.gif\" //></a>",
                                "<a onclick=\"DeleteNewsLetter("+n.NewsLetterID+");\" href=\"javascript:void(0);\"><img alt=\"delete\" border=\"0\" src=\"/areas/mvccmsoptin/content/buttons/delete.gif\" //></a>"
                            }).ToArray();

                var result = new DataTablesResponse
                {
                    iTotalRecords = dtoNewsLetters.GetPagination.iTotalRecords,
                    iTotalDisplayRecords = dtoNewsLetters.GetPagination.iTotalDisplayRecords,
                    sEcho = dataTablesRequest.sEcho,
                    sColumns = columnsToReturn,
                    aaData = dataTablesFormatted
                };

                return Json(result);
            }
            catch (Exception ex)
            {
                AppLogging.GetLogger().Error(ex.Message, ex);
                return Json(new { error = ex.Message });
            }
        }

        [Authorize(Roles = "Admin, Editor")]
        public JsonResult ListMailingLists(DataTablesRequest dataTablesRequest)
        {
            try
            {
                var columnsToReturn = "ListName,NewsLetterCount,SubscriberCount,Edit,Delete";
                var dtoLists = _service.ListLists(dataTablesRequest, columnsToReturn);
                var dataTablesFormatted = dtoLists
                    .Select(l => new string[] {    
                                l.ListName, 
                                l.NewsLetterCount.ToString(), 
                                l.SubscriberCount.ToString(), 
                                "<a href=\"/optin-manager/editlist/"+l.ListID+"\"><img border=\"0\" alt=\"edit\" src=\"/areas/mvccmsoptin/content/buttons/editlist.gif\" //></a>",
                                "<a onclick=\"DeleteList("+l.ListID+");\" href=\"javascript:void(0);\"><img alt=\"delete\" border=\"0\" src=\"/areas/mvccmsoptin/content/buttons/delete.gif\" //></a>"
                            }).ToArray();

                var result = new DataTablesResponse
                {                    
                    iTotalRecords = dtoLists.GetPagination.iTotalRecords,
                    iTotalDisplayRecords = dtoLists.GetPagination.iTotalDisplayRecords,
                    sEcho = dataTablesRequest.sEcho,
                    sColumns = columnsToReturn,
                    aaData = dataTablesFormatted
                };

                return Json(result);
            }
            catch (Exception ex)
            {
                AppLogging.GetLogger().Error(ex.Message, ex);
                return Json(new { error = ex.Message });
            }
        }

        [Authorize(Roles = "Admin, Editor")]
        public JsonResult ImportSubscribersFromPortal(List<int> listIds, string roles)
        {
            try
            {
                var listsToApply = new List<OptInList>();
                foreach (var listId in listIds)
                {
                    var listToApply = new OptInList
                    {
                        ListID = listId
                    };
                    listsToApply.Add(listToApply);
                }
                if (_service.ImportSubscribersFromPortal(true, false, string.Empty, listsToApply, roles))
                {
                    return Json(new { result = "success" });
                }
                else
                {
                    return Json(new { error = "There was a problem importing subscribers." });
                }
            }
            catch (Exception ex)
            {
                AppLogging.GetLogger().Error(ex.Message, ex);
                return Json(new { error = ex.Message });
            }
        }

        [Authorize(Roles = "Admin, Editor")]
        public JsonResult ImportSubscribersFromCSV(List<int> listIds, string emails, bool doNotAddExisting)
        {
            try
            {
                var listsToApply = new List<OptInList>();
                foreach (var listId in listIds)
                {
                    var listToApply = new OptInList
                    {
                        ListID = listId
                    };
                    listsToApply.Add(listToApply);
                }
                var subscribersToAdd = new List<OptInSubscriber>();
                foreach (var email in emails.Split(','))
                {
                    var subscriberToAdd = new OptInSubscriber
                    {
                        EMail = email.TryTrim()
                    };
                    subscribersToAdd.Add(subscriberToAdd);
                }
                if (_service.ImportSubscribersFromCSV(true, false, string.Empty, listsToApply, subscribersToAdd, doNotAddExisting))
                {
                    return Json(new { result = "success" });
                }
                else
                {
                    return Json(new { error = "There was a problem importing subscribers." });
                }
            }
            catch (Exception ex)
            {
                AppLogging.GetLogger().Error(ex.Message, ex);
                return Json(new { error = ex.Message });
            }
        }

        [Authorize(Roles = "Admin, Editor")]
        public JsonResult ListSubscribers(DataTablesRequest dataTablesRequest)
        {
            try
            {
                var columnsToReturn = "Name,Email,DoNotContact,Format,Edit,Delete";
                var subscribers = _service.ListSubscribers(dataTablesRequest, columnsToReturn);
                var dataTablesFormatted = subscribers
                    .Select(s => new string[] {    
                                s.Name, 
                                s.Email, 
                                s.DoNotContact.ToString(), 
                                s.Format,
                                "<a title='Edit' href='/optin-manager/editsubscriber/" + s.SubscriberID + "'><img border=\"0\" alt=\"edit\" src=\"/areas/mvccmsoptin/content/buttons/editlist.gif\" //></a>",
                                "<a title='Delete' onclick='Delete(\"" + s.Email + "\", " + s.SubscriberID + ")' href='javascript:void(0)'><img alt=\"delete\" border=\"0\" src=\"/areas/mvccmsoptin/content/buttons/delete.gif\" //></a>"
                            }).ToArray();

                var result = new DataTablesResponse
                {
                    iTotalRecords = subscribers.GetPagination.iTotalRecords,
                    iTotalDisplayRecords = subscribers.GetPagination.iTotalDisplayRecords,
                    sEcho = dataTablesRequest.sEcho,
                    sColumns = columnsToReturn,
                    aaData = dataTablesFormatted
                };

                return Json(result);
            }
            catch (Exception ex)
            {
                AppLogging.GetLogger().Error(ex.Message, ex);
                return Json(new { error = ex.Message });
            }
        }

        [Authorize(Roles = "Admin, Editor")]
        public JsonResult ListSubscribersForList(int id, DataTablesRequest dataTablesRequest)
        {
            try
            {
                var columnsToReturn = "Name,Email,DoNotContact,Format";
                var subscribers = _service.ListSubscribers(dataTablesRequest, columnsToReturn, id);
                var dataTablesFormatted = subscribers
                    .Select(s => new string[] {    
                                s.Name, 
                                s.Email, 
                                s.DoNotContact.ToString(), 
                                s.Format
                            }).ToArray();

                var result = new DataTablesResponse
                {
                    iTotalRecords = subscribers.GetPagination.iTotalRecords,
                    iTotalDisplayRecords = subscribers.GetPagination.iTotalDisplayRecords,
                    sEcho = dataTablesRequest.sEcho,
                    sColumns = columnsToReturn,
                    aaData = dataTablesFormatted
                };

                return Json(result);
            }
            catch (Exception ex)
            {
                AppLogging.GetLogger().Error(ex.Message, ex);
                return Json(new { error = ex.Message });
            }
        }
    }
}
